package org.msn.gui.controller;

import javafx.application.Platform;
import javafx.fxml.FXML;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import lombok.SneakyThrows;
import org.bytedeco.javacv.*;
import org.msn.gui.init.SelfSoundAndVideoInit;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.*;
import java.util.ResourceBundle;

public class SelfVideoController extends SelfSoundAndVideoInit {
    private OpenCVFrameGrabber grabber;
    public static volatile boolean stop = true;

    @FXML
    private ImageView video;

    @Override
    public void initialize(URL url, ResourceBundle resourceBundle) {
        new SelfVideoThread().start();
    }

    public class SelfVideoThread extends Thread {
        @SneakyThrows
        @Override
        public void run() {
            grabber = new OpenCVFrameGrabber(0);
            grabber.start();

            try {
                while (stop) {
                    Platform.runLater(new Runnable() {
                        @SneakyThrows
                        @Override
                        public void run() {
                            if (grabber == null) {
                                return;
                            }

                            loadVideoToSelfAndSendVideoToOther();
                        }
                    });

                    sleep(50);
                }
            } finally {
                closeVideoEvent();
            }
        }

        private void loadVideoToSelfAndSendVideoToOther() throws FrameGrabber.Exception, SocketException {
            Frame frame = grabber.grabFrame();
            Image convert = new JavaFXFrameConverter().convert(frame);
            video.setImage(convert);

            BufferedImage bufferedImage = new Java2DFrameConverter()
                    .getBufferedImage(frame);

            DatagramSocket datagramSocket = new DatagramSocket();

            userIP.stream().forEach((v) -> {
                try {
                    String[] str = v.split(":");
                    sendVideoToOther(datagramSocket, bufferedImage, InetAddress.getByName(str[0]), Integer.parseInt(str[1]));
                } catch (IOException e) {
                    e.printStackTrace();
                }
            });
        }

        private void sendVideoToOther(DatagramSocket datagramSocket, BufferedImage bufferedImage, InetAddress remoteIP, int remotePort)
                throws IOException {
            byte[] content = new byte[65507];
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            ImageIO.write(bufferedImage, "jpg", out);
            content = out.toByteArray();

            DatagramPacket datagramPacket = new DatagramPacket(content, content.length, remoteIP, remotePort);
            datagramSocket.send(datagramPacket);
        }

        private void closeVideoEvent() throws FrameGrabber.Exception {
            grabber.stop();
            grabber.release();
        }
    }
}
